<template>
  <div class="app-container">
    <el-row>
      <!-- 左侧卡片（占 16 列） -->
      <el-col :span="16">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <el-button style="float: right;" size="small" type="danger" @click="goBack">关闭</el-button>
          </div>

          <el-tabs tab-position="top" v-model="activeName" @tab-click="handleClick">
            <!-- 表单信息 -->
            <el-tab-pane label="表单信息" name="1">
              <el-col :span="24">
                <v-form-render ref="vFormRef" />
              </el-col>
            </el-tab-pane>

            <!-- 流程流转记录 -->
            <el-tab-pane label="流转记录" name="2">
              <el-col :span="24">
                <div class="block">
                  <el-timeline>
                    <el-timeline-item
                      v-for="(item, index) in flowRecordList"
                      :key="index"
                      :icon="setIcon(item.finishTime)"
                      :color="setColor(item.finishTime)"
                    >
                      <p style="font-weight: 700">{{ item.taskName }}</p>
                      <el-card :body-style="{ padding: '10px' }">
                        <el-descriptions class="margin-top" :column="1" size="small" border>
                          <el-descriptions-item v-if="item.assigneeName" label-class-name="my-label">
                            <template #label><i class="el-icon-user"></i>办理人</template>
                            {{ item.assigneeName }}
                            <el-tag type="info" size="default">{{ item.deptName }}</el-tag>
                          </el-descriptions-item>
                          <el-descriptions-item v-if="item.candidate" label-class-name="my-label">
                            <template #label><i class="el-icon-user"></i>候选办理</template>
                            {{ item.candidate }}
                          </el-descriptions-item>
                          <el-descriptions-item label-class-name="my-label">
                            <template #label><i class="el-icon-date"></i>接收时间</template>
                            {{ item.createTime }}
                          </el-descriptions-item>
                          <el-descriptions-item v-if="item.finishTime" label-class-name="my-label">
                            <template #label><i class="el-icon-date"></i>处理时间</template>
                            {{ item.finishTime }}
                          </el-descriptions-item>
                          <el-descriptions-item v-if="item.duration" label-class-name="my-label">
                            <template #label><i class="el-icon-time"></i>耗时</template>
                            {{ item.duration }}
                          </el-descriptions-item>
                          <el-descriptions-item v-if="item.comment" label-class-name="my-label">
                            <template #label><i class="el-icon-tickets"></i>处理意见</template>
                            {{ item.comment.comment }}
                          </el-descriptions-item>
                        </el-descriptions>
                      </el-card>
                    </el-timeline-item>
                  </el-timeline>
                </div>
              </el-col>
            </el-tab-pane>
            <!-- 流程图 -->
            <el-tab-pane label="流程图" name="3">
              <BpmnViewer :flow-data="flowData" :proc-ins-id="taskForm.procInsId" />
            </el-tab-pane>
          </el-tabs>

          <!-- 审批任务 -->
          <el-dialog :title="completeTitle" v-model="completeOpen" width="30%" append-to-body>
            <el-form ref="taskFormRef" :model="taskForm">
              <el-form-item prop="targetKey">
                <FlowUser v-if="checkSendUser" :check-type="checkType" @handleUserSelect="handleUserSelect"></FlowUser>
                <FlowRole v-if="checkSendRole" @handleRoleSelect="handleRoleSelect"></FlowRole>
              </el-form-item>
              <el-form-item
                label="处理意见"
                label-width="80px"
                prop="comment"
                :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]"
              >
                <el-input type="textarea" v-model="taskForm.comment" placeholder="请输入处理意见" />
              </el-form-item>
            </el-form>
            <template #footer>
              <el-button @click="completeOpen = false">取 消</el-button>
              <el-button type="primary" @click="taskComplete">确 定</el-button>
            </template>
          </el-dialog>

          <!-- 退回流程 -->
          <el-dialog :title="returnTitle" v-model="returnOpen" width="30%" append-to-body>
            <el-form ref="taskFormRef" :model="taskForm" label-width="80px">
              <el-form-item label="退回节点" prop="targetKey">
                <el-radio-group v-model="taskForm.targetKey">
                  <el-radio-button
                    v-for="item in returnTaskList"
                    :key="item.id"
                    :value="item.id"
                  >{{ item.name }}
                  </el-radio-button>
                </el-radio-group>
              </el-form-item>
              <el-form-item
                label="退回意见"
                prop="comment"
                :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]"
              >
                <el-input style="width: 80%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见" />
              </el-form-item>
            </el-form>
            <template #footer>
              <el-button @click="returnOpen = false">取 消</el-button>
              <el-button type="primary" @click="taskReturn">确 定</el-button>
            </template>
          </el-dialog>

          <!-- 驳回流程 -->
          <el-dialog :title="rejectTitle" v-model="rejectOpen" width="40%" append-to-body>
            <el-form ref="taskFormRef" :model="taskForm" label-width="80px">
              <el-form-item
                label="驳回意见"
                prop="comment"
                :rules="[{ required: true, message: '请输入意见', trigger: 'blur' }]"
              >
                <el-input style="width: 50%" type="textarea" v-model="taskForm.comment" placeholder="请输入意见" />
              </el-form-item>
            </el-form>
            <template #footer>
              <el-button @click="rejectOpen = false">取 消</el-button>
              <el-button type="primary" @click="taskReject">确 定</el-button>
            </template>
          </el-dialog>
        </el-card>
      </el-col>

      <el-col :span="1"></el-col>

      <!-- 右侧卡片（占 7 列） -->
      <el-col :span="7">
        <el-card>
          <div slot="header" class="clearfix">
            <span class="el-icon-document">待办任务</span>
            <el-tag style="margin-left:10px">发起人:{{ startUser }}</el-tag>
            <el-tag>任务节点:{{ taskName }}</el-tag>
          </div>
          <el-divider />

          <el-form-item
            label="操作"
            label-width="50px"
            prop="comment"
            :rules="[{ required: true, message: '请输入处理意见', trigger: 'blur' }]"
          >
            <el-button type="success" @click="handleComplete">同 意</el-button>
            <el-button type="danger" @click="handleReject">驳 回</el-button>
            <el-button type="warning" @click="handleReturn">退 回</el-button>
          </el-form-item>

          <!-- <div style="margin-left:10%;margin-bottom: 20px;font-size: 14px;">
            <el-button type="primary" @click="handleComplete">审 批</el-button>
            <el-button type="danger" @click="handleReject">驳 回</el-button>
          </div> -->

        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import {flowRecord} from "@/api/flowable/finished";
import {flowXmlAndNode} from "@/api/flowable/definition";
import { ref, reactive, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { flowTaskForm, getNextFlowNode, complete, rejectTask, returnList, returnTask, delegate } from '@/api/flowable/todo';
import BpmnViewer from '@/components/Process/viewer';
import FlowUser from '@/components/flow/User';
import FlowRole from '@/components/flow/Role';

const vFormRef = ref(null);
const taskFormRef = ref(null);
const route = useRoute();
const router = useRouter();

const activeName = ref('1');
const flowData = ref({});       // 流程数据
const flowRecordList = ref([]); // 流程流转数据
const taskForm = reactive({
  returnTaskShow: false,    // 是否展示回退表单
  delegateTaskShow: false,  // 是否展示回退表单
  defaultTaskShow: true,    // 默认处理
  comment: '',              // 意见内容
  procInsId: '',            // 流程实例编号
  instanceId: '',           // 流程实例编号
  deployId: '',             // 流程定义编号
  taskId: '',               // 流程任务编号
  procDefId: '',            // 流程编号
  targetKey: '',
  variables: {},
});
const returnTaskList = ref([]);   // 回退列表数据
const completeTitle = ref(null);
const completeOpen = ref(false);
const returnTitle = ref(null);
const returnOpen = ref(false);
const rejectOpen = ref(false);
const rejectTitle = ref(null);
const checkSendUser = ref(false); // 是否展示人员选择模块
const checkSendRole = ref(false); // 是否展示角色选择模块
const checkType = ref('single');  // 选择类型
const taskName = ref(null);       // 任务节点
const startUser = ref(null);      // 发起人信息,
const multiInstanceVars = ref('');// 会签节点
const formJson = ref({});
const delegateTaskShow = ref(false);
const defaultTaskShow = ref(false);


onMounted(() => {
  if (route.query) {
    taskName.value = route.query.taskName;
    startUser.value = route.query.startUser;
    taskForm.deployId = route.query.deployId;
    taskForm.taskId = route.query.taskId;
    taskForm.procInsId = route.query.procInsId;
    taskForm.executionId = route.query.executionId;
    taskForm.instanceId = route.query.procInsId;
    // 流程任务获取变量信息
    if (taskForm.taskId) {
      getFlowTaskForm(taskForm.taskId);
    }
    getFlowRecordList(taskForm.procInsId, taskForm.deployId);
  }
});

const handleClick = (tab) => {
  if (tab.props.name === '3') {
    flowXmlAndNode({ procInsId: taskForm.procInsId, deployId: taskForm.deployId }).then((res) => {
      flowData.value = res.data;
    });
  }
};

const setIcon = (val) => {
  return val ? 'el-icon-check' : 'el-icon-time';
};

const setColor = (val) => {
  return val ? '#2bc418' : '#b3bdbb';
};

// 用户信息选中数据
const handleUserSelect = (selection) => {
  if (selection) {
    if (Array.isArray(selection)) {
      const selectVal = selection.map((item) => item.userId.toString());
      if (multiInstanceVars.value) {
        taskForm.variables[multiInstanceVars.value] = selectVal;
      } else {
        taskForm.variables.approval = selectVal.join(',');
      }
    } else {
      taskForm.variables.approval = selection.userId.toString();
    }
  }
};

// 角色信息选中数据
const handleRoleSelect = (selection) => {
  if (selection) {
    if (Array.isArray(selection)) {
      const selectVal = selection.map((item) => item.roleId.toString());
      taskForm.variables.approval = selectVal.join(',');
    } else {
      taskForm.variables.approval = selection;
    }
  }
};

// 流程流转记录
const getFlowRecordList = (procInsId, deployId) => {
  const params = { procInsId, deployId };
  flowRecord(params).then((res) => {
    flowRecordList.value = res.data.flowList;
  }).catch(() => {
    goBack();
  });
};

// 流程节点表单
const getFlowTaskForm = (taskId) => {
  // 提交流程申请时填写的表单存入了流程变量中后续任务处理时需要展示
  flowTaskForm({ taskId }).then((res) => {
    // 回显表单
    vFormRef.value.setFormJson(res.data.formJson);
    formJson.value = res.data.formJson;
    vFormRef.value.setFormData(res.data);
  });
};

// 委派任务
const handleDelegate = () => {
  delegateTaskShow.value = true;
  defaultTaskShow.value = false;
};

// 委派任务
const submitDeleteTask = () => {
  taskFormRef.validate(valid => {
    if (valid) {
      delegate(taskForm).then(res => {
        ElMessage.success(res.msg);
        goBack();
      });
    }
  });
};

// 返回页面
const goBack = () => {
  const obj = { path: '/task/todo', query: { t: Date.now() } };
  router.push(obj);
};

// 驳回任务
const handleReject = () => {
  rejectOpen.value = true;
  rejectTitle.value = '驳回流程';
};

const taskReject = () => {
  taskFormRef.value.validate((valid) => {
    if (valid) {
      rejectTask(taskForm).then((res) => {
        ElMessage.success(res.msg);
        goBack();
      });
    }
  });
};

// 可退回任务列表
const handleReturn = () => {
  returnOpen.value = true;
  returnTitle.value = '退回流程';
  returnList(taskForm).then((res) => {
    returnTaskList.value = res.data;
  });
};

// 提交退回任务
const taskReturn = () => {
  taskFormRef.value.validate((valid) => {
    if (valid) {
      returnTask(taskForm).then((res) => {
        ElMessage.success(res.msg);
        goBack();
      });
    }
  });
};

// 加载审批任务弹窗
const handleComplete = () => {
  completeOpen.value = true;
  completeTitle.value = '流程审批';
  submitForm();
};

// 用户审批任务
const taskComplete = () => {
  if (!taskForm.variables && checkSendUser.value) {
    ElMessage.error('请选择流程接收人员!');
    return;
  }
  if (!taskForm.variables && checkSendRole.value) {
    ElMessage.error('请选择流程接收角色组!');
    return;
  }
  if (!taskForm.comment) {
    ElMessage.error('请输入审批意见!');
    return;
  }
  complete(taskForm).then((response) => {
    ElMessage.success(response.msg);
    goBack();
  });
};

// 申请流程表单数据提交
const submitForm = () => {
  getNextFlowNode({ taskId: taskForm.taskId }).then((res) => {
    vFormRef.value.getFormData().then((formData) => {
      Object.assign(taskForm.variables, formData);
      taskForm.variables.formJson = formJson.value;
    });
    const data = res.data;
    if (data && data.dataType === 'dynamic') {
      if (data.type === 'assignee') {
        checkSendUser.value = true;
        checkType.value = 'single';
      } else if (data.type === 'candidateUsers') {
        checkSendUser.value = true;
        checkType.value = 'multiple';
      } else if (data.type === 'candidateGroups') {
        checkSendRole.value = true;
      } else {
        multiInstanceVars.value = data.vars;
        checkSendUser.value = true;
        checkType.value = 'multiple';
      }
    }
  });
};
</script>

<style lang="scss" scoped>
.test-form {
  margin: 15px auto;
  width: 800px;
  padding: 15px;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}

.clearfix:after {
  clear: both;
}

.box-card {
  width: 100%;
  margin-bottom: 20px;
}

.el-tag + .el-tag {
  margin-left: 10px;
}

.my-label {
  background: #E1F3D8;
}
</style>